package com.ele.client.editor;

import com.ele.client.Presenter;
import com.ele.client.rpc.ApplicationServiceAsync;
import com.ele.client.rpc.SimpleAsyncCallback;
import com.ele.client.util.PathHelper;
import com.ele.model.Question;
import com.ele.model.Section;
import com.ele.model.Word;
import com.github.gwtbootstrap.client.ui.*;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.TextArea;
import com.github.gwtbootstrap.client.ui.TextBox;
import com.github.gwtbootstrap.client.ui.constants.AlertType;
import com.github.gwtbootstrap.client.ui.constants.BackdropType;
import com.github.gwtbootstrap.client.ui.event.ClosedEvent;
import com.github.gwtbootstrap.client.ui.event.ClosedHandler;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.*;

import java.util.ArrayList;
import java.util.List;

public class SectionPresenter implements Presenter {

    public interface Display {
        Widget asWidget();

        TextBox getNameTextBox();

        TextArea getRuleTextArea();

        Button getAddQuestionButton();

        FlowPanel getQuestionsPlaceholder();

        FlowPanel getWordsPanel();

        Button getAddWordButton();

        Button getSaveButton();

        Button getPrevButton();

        Button getNextButton();
    }

    private final ApplicationServiceAsync rpcService;
    private final HandlerManager eventBus;
    private final Display display;

    private Section value;

    private int questionLabelCounter = 1;
    private List<QuestionPresenter> presenters = new ArrayList<QuestionPresenter>();

    public SectionPresenter(ApplicationServiceAsync rpcService, HandlerManager eventBus, Display display) {
        this.rpcService = rpcService;
        this.eventBus = eventBus;
        this.display = display;
    }

    public void bind() {
        display.getAddQuestionButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                Question question = createEmptyQuestion();
                addQuestionControl(question);
                presenters.get(presenters.size()-1).setFocus(true);
            }
        });

        display.getAddWordButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                final Modal modal = new Modal(true);
                modal.setBackdrop(BackdropType.NORMAL);
                modal.setTitle("Add Word");
                modal.setKeyboard(true);
                modal.setWidth("300px");
                modal.add(new FormLabel("Word"));
                final TextBox wordTextBox = new TextBox();
                wordTextBox.setHeight("26px");
                modal.add(wordTextBox);
                modal.add(new FormLabel("Translation"));
                final TextBox translationTextBox = new TextBox();
                translationTextBox.setHeight("26px");
                modal.add(translationTextBox);

                ModalFooter footer = new ModalFooter();
                Button cancelButton = new Button("Cancel");
                cancelButton.addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        modal.hide();
                    }
                });
                footer.add(cancelButton);
                Button addButton = new Button("Add");
                addButton.addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        Word word = new Word();
                        word.setText(wordTextBox.getText());
                        word.setTranslation(translationTextBox.getText());
                        if (value.getWords() == null) {
                            value.setWords(new ArrayList<Word>());
                        }
                        value.getWords().add(word);
                        addWordControl(word);
                        modal.hide();
                    }
                });
                footer.add(addButton);
                modal.add(footer);



                modal.show();
            }
        });

        display.getSaveButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                Section value = getValue();

                display.getSaveButton().state().loading();
                rpcService.saveSection(value, new SimpleAsyncCallback<Section>() {
                    @Override
                    public void onSuccess(Section section) {
                        display.getSaveButton().state().reset();
                        setValue(section);
                        PathHelper.setId(section.getId());
                    }
                });
            }
        });

        display.getPrevButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                goToPrev();
            }
        });

        display.getNextButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                goToNext();
            }
        });
    }

    private void goToNext() {
        Long id = value.getId();
        if (id != null) {
            History.newItem("action=editor&id=" + (id + 1));
        }
    }

    private void goToPrev() {
        Long id = value.getId();
        if (id != null) {
            History.newItem("action=editor&id=" + (id - 1));
        }
    }

    private void addQuestionControl(Question question) {
        QuestionView view = new QuestionView();
        QuestionPresenter presenter = new QuestionPresenter(rpcService, eventBus, view, this);
        presenter.setValue(question);
        presenters.add(presenter);

        display.getQuestionsPlaceholder().add(view);
    }

    public void go(final HasWidgets container) {
        bind();
        container.clear();
        container.add(display.asWidget());

        Long id = PathHelper.getId();
        if (id != null) {
            loadSection(id);
        } else {
            Section section = new Section();
            setValue(section);
        }

        display.getNameTextBox().setFocus(true);
    }

    private void loadSection(Long id) {
        rpcService.getSection(id, new SimpleAsyncCallback<Section>() {
            @Override
            public void onSuccess(Section section) {
                setValue(section);
            }
        });
    }

    public void setValue(Section section) {
        value = section;

        if (section != null) {
            display.getNameTextBox().setValue(section.getName());
            display.getRuleTextArea().setValue(section.getRule());

            presenters.clear();
            display.getQuestionsPlaceholder().clear();

            if (section.getQuestions() != null) {
                for (Question question : section.getQuestions()) {
                    addQuestionControl(question);
                }
            }

            if (section.getWords() != null) {
                for (Word word : section.getWords()) {
                    addWordControl(word);
                }
            }

            PathHelper.setId(value.getId());
        } else {
            value = new Section();
            PathHelper.setId(null);
        }
    }

    private void addWordControl(Word word) {
        final AlertBlock block = new AlertBlock(word.getText());
        block.setType(AlertType.INFO);
        block.getElement().getStyle().setFloat(Style.Float.LEFT);
        block.getElement().getStyle().setMarginRight(5, Style.Unit.PX);
        block.setWidth("100px");

        block.addClosedHandler(new ClosedHandler() {
            @Override
            public void onClosed(ClosedEvent closedEvent) {
                String text = block.getText();
                for (Word w : value.getWords()) {
                    if (text.equals(w.getText())) {
                        value.getWords().remove(w);
                    }
                }
            }
        });

        display.getWordsPanel().add(block);
    }

    private Question createEmptyQuestion() {
        Question question = new Question();
//        question.setText("Question #" + questionLabelCounter + " Text");
        questionLabelCounter++;
        return question;
    }

    public void remove(QuestionPresenter presenter) {
        presenter.getDisplay().asWidget().removeFromParent();
        presenters.remove(presenter);
    }

    public Display getDisplay() {
        return display;
    }

    public Section getValue() {
        value.setName(display.getNameTextBox().getValue());
        value.setRule(display.getRuleTextArea().getValue());

        List<Question> questions = new ArrayList<Question>();
        for (QuestionPresenter presenter : presenters) {
            Question question = presenter.getValue();
            questions.add(question);
        }
        value.setQuestions(questions);

        return value;
    }
}
